package base

import (
	"errors"
	kinit "longblog/work/base/initialize"
	kmiddleware "longblog/work/base/middleware"
	kroute "longblog/work/base/route"
	kcode "longblog/work/code"
	kdaocms "longblog/work/dao/cms"
	"net/http"

	"github.com/gin-contrib/sessions"
	"github.com/gin-gonic/gin"
)

const (
	MIDDLE_TYPE_CHECK_LOGIN      = 0
	MIDDLE_TYPE_CHECK_PERMISSION = 1
	MIDDLE_TYPE_NO_CHECK_LOGIN   = 2
)

func Wrap(Method string, Path string, f func(*gin.Context), types int) kroute.RouteWrapStruct {
	//insertMenu(Path)
	wp := kroute.RouteWrapStruct{
		Method: Method,
		Path:   Path,
	}
	wp.F = func(c *gin.Context) {
		method := c.Request.Method
		StorePreventToken(c, method)
		if types == MIDDLE_TYPE_CHECK_LOGIN || types == MIDDLE_TYPE_CHECK_PERMISSION {
			err := CheckLogin(c)
			if err != nil {
				kinit.LogError.Println(err)
				c.Redirect(http.StatusMovedPermanently, "/login")
				return
			}
			//检查权限
			if types == MIDDLE_TYPE_CHECK_PERMISSION {
				if ok := kmiddleware.CheckPermissionIsOk(c); !ok {
					if method == "POST" || method == "PUT" || method == "DELETE" || method == "PATCH" {
						SendErrorTokenJsonStr(c, kcode.WRONG_PERMISSION_NO_HAVE, "")
					} else {
						c.Redirect(http.StatusMovedPermanently, "/nopermission")
					}
					return
				}
				//记录日志
				kmiddleware.StoreLogRecord(c, "")
			}
			//防止未响应前重复提交
			if ok := CheckForm(c, method); !ok {
				SendErrorJsonStr(c, kcode.WRONG_REPEAT_FORM, "")
				return
			}
		}
		f(c)
	}
	return wp
}

func CheckLogin(c *gin.Context) error {

	session := sessions.Default(c)
	//kinit.LogError.Println(session)

	v := session.Get("user")
	if v == nil {
		return errors.New("session is nil")
	}
	c.Set("user", v)
	c.Set("user_name", session.Get("user_name"))
	return nil
}

func StorePreventToken(c *gin.Context, method string) {
	if method == "GET" || method == "HEAD" || method == "OPTIONS" {
		token := kmiddleware.GetPreventToken(c)
		c.Set("token", token)
	}
}

func CheckForm(c *gin.Context, method string) bool {
	if method == "POST" || method == "PUT" || method == "DELETE" || method == "PATCH" {
		token := GetParam(c, "token")
		return kmiddleware.VerifyPreventToken(c, token)
	}
	return true
}

func InsertMenu(path string) {
	if obj := kdaocms.GetCmsAdminPermissionsByPath(nil, path); obj.ID > 0 {
		return
	}
	if _, err := kdaocms.InsertCmsAdminPermissions(nil, "待分配的菜单", 0, path, 0); err != nil {
		kinit.LogError.Println(err)
	}
}
